package in.ac.dei.edrp.cms.daoimpl.activitymaster;

import java.util.ArrayList;
import java.util.List;

import in.ac.dei.edrp.cms.constants.CRConstant;
import in.ac.dei.edrp.cms.controller.activitymaster.StartActivityController;
import in.ac.dei.edrp.cms.dao.activitymaster.StartActivityDao;
import in.ac.dei.edrp.cms.dao.registration.prestagingdao.TransferNORInPSTDAO;
import in.ac.dei.edrp.cms.daoimpl.registration.mastertransferdaoimpl.TransferTempIntoMaster;
import in.ac.dei.edrp.cms.daoimpl.registration.prestagingdaoimpl.TransfertNORInPSTFunction;
import in.ac.dei.edrp.cms.daoimpl.resultprocessing.PreProcessForResult;
import in.ac.dei.edrp.cms.daoimpl.studentregistration.ProbableToActualDaoImpl;
import in.ac.dei.edrp.cms.daoimpl.studentregistration.StudentMasterImpl;
import in.ac.dei.edrp.cms.daoimpl.studentregistration.preProcessImpl;
import in.ac.dei.edrp.cms.domain.activitymaster.CountProcessRecorList;
import in.ac.dei.edrp.cms.domain.activitymaster.StartActivityBean;
import in.ac.dei.edrp.cms.domain.registration.prestaging.ActivityMasterBean;
import in.ac.dei.edrp.cms.domain.registration.prestaging.MasterTransferBean;
import in.ac.dei.edrp.cms.domain.studentregistration.StudentInfoGetter;
import in.ac.dei.edrp.cms.domain.utility.ErrorLogs;
import in.ac.dei.edrp.cms.utility.CRException;
import in.ac.dei.edrp.cms.utility.RegistrationFunction;
import in.ac.dei.edrp.cms.utility.StudentTrackingFunction;

import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import org.springframework.transaction.SavepointManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import com.ibatis.sqlmap.client.SqlMapClient;

public class StartActivityDaoImpl implements StartActivityDao{

	public static final Logger logger = Logger.getLogger(StartActivityDaoImpl.class);

	protected SqlMapClient sqlMapClient = null;

	String userId="Deepak Pandey";
    public void setSqlMapClient(SqlMapClient sqlMapClient) {
        this.sqlMapClient = sqlMapClient;
    }

	private TransactionTemplate transactionTemplate=null;

	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}

	/**
	 * Returns the list of process id and semester code and name using SYSTEM_TABLE_TWO according to
	 * group code in input object i.e startActivityBean
	 * if group code in object is PRCMST, it returns process_id and values
	 * and if group code in object is SEMCOD, it returns semester code and name
	 */
	public List<StartActivityBean> getProcessList(
			StartActivityBean startActivityBean) {
		// TODO Auto-generated method stub

		List<StartActivityBean> processList=new ArrayList<StartActivityBean>();
		try{

			processList=sqlMapClient.queryForList("startActivity.getProcessList",startActivityBean);

			System.out.println("processList"+processList);
		}catch(Exception e){
			System.out.println("Exception is: "+e.getMessage());
			logger.info("Exception in getting process list"+e.getMessage());
		}
		return processList;
	}

	/**
	 * Return data for processGridList
	 */
	public List<StartActivityBean> getProcessGridList(
			StartActivityBean startActivityBean) {
		// TODO Auto-generated method stub

		List<StartActivityBean> processGridList=new ArrayList<StartActivityBean>();
		try{

			processGridList=sqlMapClient.queryForList("startActivity.getProcessGridList",startActivityBean);

			System.out.println("processList"+processGridList);
		}catch(Exception e){
			System.out.println("Exception is: "+e.getMessage());
			logger.info("Exception in getting process grid list"+e.getMessage());
		}
		return processGridList;
	}

	/**
	 * Returns list for activityProcessGridList
	 */
	public List<StartActivityBean> getProcessActivityGridList(
			StartActivityBean startActivityBean) {
		// TODO Auto-generated method stub

		List<StartActivityBean> processGridList=new ArrayList<StartActivityBean>();
		try{
			System.out.println(startActivityBean.getEntityId()+startActivityBean.getProgramCourseKey()+startActivityBean.getSemesterStartDate()+startActivityBean.getSemesterEndDate()+startActivityBean.getProcessId());
			processGridList=sqlMapClient.queryForList("startActivity.getActivityList",startActivityBean);

			System.out.println("process activity List"+processGridList);
		}catch(Exception e){
			System.out.println("Exception is: "+e.getMessage());
			logger.info("Exception in getting process activity grid list"+e.getMessage());
		}
		return processGridList;
	}

	/**
	 * get Program course key for given input
	 *
	 */
	public List<StartActivityBean> getProgramCourseKey(
			StartActivityBean startActivityBean) {
		// TODO Auto-generated method stub

		List<StartActivityBean> programCourseKey=new ArrayList<StartActivityBean>();
		try{
			//if branch is not selected, then all branch and specialization for this program and semesterwill be in list
			//if specialization is not selected, then all specialization for this program ,branch and semester and will be in list
			//If all are selected, then a program course key according to program, branch and specialization and semester
			System.out.println(startActivityBean.getBranchId()+startActivityBean.getSpecializationId());
			if(startActivityBean.getBranchId().equalsIgnoreCase("")){
					//List according to program and semester
					System.out.println("Coming inside program and semester");
					if(startActivityBean.getSpecializationId().equalsIgnoreCase("")){
						//List according to program,branch and semester
						System.out.println("Coming inside program and branch with semester");
						programCourseKey=sqlMapClient.queryForList("startActivity.getProgCoursekey",startActivityBean);
						System.out.println("Coming inside  program and branch with semester"+programCourseKey.size());
					}
					
				}
				else{
					if(startActivityBean.getSpecializationId().equalsIgnoreCase("")){
						//List according to program,branch and semester
						System.out.println("Coming inside program and branch with semester");
						programCourseKey=sqlMapClient.queryForList("startActivity.getProgCoursekeyBranch",startActivityBean);
						System.out.println("Coming inside program and branch and semester"+programCourseKey.size());
					}
					else{
						////List according to program,branch,specialzation and semester
						System.out.println("Coming inside program and semester");
						programCourseKey=sqlMapClient.queryForList("startActivity.getProgCoursekeySpecialiazation",startActivityBean);
						System.out.println("Coming inside program branch and specialization"+programCourseKey.size());

					}
				}


		}catch(Exception e){
			System.out.println("Exception is: "+e.getMessage());
			logger.info("Exception in program course key"+e.getMessage());
		}
		return programCourseKey;
	}



	//This method is responsible to run different activities.
	//Accordint to their process id, responsible method will be called
	public CountProcessRecorList startActivity(final StartActivityBean startActivityBean) {
		// TODO Auto-generated method stub
		final CountProcessRecorList countListforUI=new CountProcessRecorList(0,0,0,0,false);;
		

		System.out.println(startActivityBean.getProcessId()+startActivityBean.getActivityId()+
				startActivityBean.getEntityId()+startActivityBean.getProgramId()+startActivityBean.getBranchId()+
				startActivityBean.getSpecializationId()+startActivityBean.getSemesterCode()+
				startActivityBean.getSemesterStartDate()+startActivityBean.getSemesterEndDate()
				+startActivityBean.getActivityStatus()+startActivityBean.getActivitySequence()+
				startActivityBean.getProgramCourseKey()+startActivityBean.getProgramName()+startActivityBean.getBranchName()+
				startActivityBean.getSpecializationName()+startActivityBean.getSemesterName()+
				startActivityBean.getSessionStartDate()+startActivityBean.getSessionEndDate());
		
		final ErrorLogs errorLogs=new ErrorLogs(startActivityBean.getEntityId(),startActivityBean.getProgramId(),
				startActivityBean.getBranchId(),startActivityBean.getSpecializationId(),
				startActivityBean.getSemesterCode(),startActivityBean.getSemesterStartDate(),startActivityBean.getSemesterEndDate(),
				startActivityBean.getProcessId(),startActivityBean.getActivityId());


		try{
			 

			final String activityCode=startActivityBean.getActivityId();
			final String processCode=startActivityBean.getProcessId();

				transactionTemplate.execute(new TransactionCallbackWithoutResult(){
					//Object savepoint=null;
					
				
						CountProcessRecorList countList=new CountProcessRecorList(0,0,0,0,false);
						
						
						//Object save=null;
						@Override
						public void doInTransactionWithoutResult(TransactionStatus status) {
								// TODO Auto-generated method stub
							try{
														 
							int processCounter=new StudentTrackingFunction(sqlMapClient,transactionTemplate).batchProcessExist(errorLogs)+1;

							errorLogs.setProcessCounter(processCounter);

							sqlMapClient.queryForList("startActivity.getLockForActivity",startActivityBean);

								if(startActivityBean.getActivityStatus().equalsIgnoreCase(CRConstant.READY_STATUS)||
										startActivityBean.getActivityStatus().equalsIgnoreCase(CRConstant.ERROR_STATUS)){

									if(startActivityBean.getActivitySequence()==1){
										sqlMapClient.update("startActivity.updateProcessStartDate", startActivityBean);
										sqlMapClient.update("startActivity.updateActivityStartDate", startActivityBean);
									}
									else{
										if(!startActivityBean.getActivityStatus().equalsIgnoreCase(CRConstant.ERROR_STATUS)){
										sqlMapClient.update("startActivity.updateActivityStartDate", startActivityBean);
										}
									}
								}



						//If process is registration
			if(processCode.equalsIgnoreCase("REG")){
			//PR1= Process1 Method TransferNORInPST method will be called.
			if(activityCode.equalsIgnoreCase("PR1")){
				System.out.println("program id in PR1:"+startActivityBean.getProgramId());
				ActivityMasterBean activityMasterBean=new ActivityMasterBean(startActivityBean.getUniversityId(),
						startActivityBean.getProcessId(),startActivityBean.getActivityId(),
						startActivityBean.getEntityId(),startActivityBean.getProgramId(),startActivityBean.getBranchId(),
						startActivityBean.getSpecializationId(),startActivityBean.getSemesterCode(),
						startActivityBean.getSemesterStartDate(),startActivityBean.getSemesterEndDate(),CRConstant.ACTIVE_STATUS,
						startActivityBean.getUserId(),startActivityBean.getSessionStartDate(),startActivityBean.getSessionEndDate(),
						processCounter);

				countList=new TransfertNORInPSTFunction(sqlMapClient,transactionTemplate).transferNorinPST(activityMasterBean);
				logger.info("Activity : "+startActivityBean.getActivityId()+"for "+startActivityBean.getProgramCourseKey()+" executed successfully");
			}


			//PR9=Probable to actual transfer
			if(activityCode.equalsIgnoreCase("PR9")){
				  StudentInfoGetter progDetails=new StudentInfoGetter();
				  	progDetails.setProgramId(startActivityBean.getProgramId());
			        progDetails.setBranchCode(startActivityBean.getBranchId());
			        progDetails.setNewSpecialization(startActivityBean.getSpecializationId());
			        progDetails.setEntityId(startActivityBean.getEntityId());
			        progDetails.setSemesterCode(startActivityBean.getSemesterCode());
			        progDetails.setSessionStartDate(startActivityBean.getSemesterStartDate());
			        progDetails.setSessionEndDate(startActivityBean.getSemesterEndDate());
			        progDetails.setModifierId("process");
			        countList= new ProbableToActualDaoImpl(sqlMapClient, transactionTemplate).transferOfProbables(progDetails);

			}


			//ENR= Enrollment number generation will be called
						if(activityCode.equalsIgnoreCase("ENR")){
							ActivityMasterBean activityMasterBean=new ActivityMasterBean(startActivityBean.getUniversityId(),
									startActivityBean.getProcessId(),startActivityBean.getActivityId(),
									startActivityBean.getEntityId(),startActivityBean.getProgramId(),startActivityBean.getBranchId(),
									startActivityBean.getSpecializationId(),startActivityBean.getSemesterCode(),
									startActivityBean.getSemesterStartDate(),startActivityBean.getSemesterEndDate(),CRConstant.ACTIVE_STATUS,
									startActivityBean.getUserId(),startActivityBean.getSessionStartDate(),startActivityBean.getSessionEndDate(),
									processCounter);

							countList = new StudentMasterImpl(sqlMapClient,transactionTemplate).generateEnrollmentNumbers(activityMasterBean);

							logger.info("Activity : "+startActivityBean.getActivityId()+"for "+startActivityBean.getProgramCourseKey()+" executed successfully");

						}

						//ROL=Roll number generation will be called
						if(activityCode.equalsIgnoreCase("ROL")){
							ActivityMasterBean activityMasterBean=new ActivityMasterBean(startActivityBean.getUniversityId(),
									startActivityBean.getProcessId(),startActivityBean.getActivityId(),
									startActivityBean.getEntityId(),startActivityBean.getProgramId(),startActivityBean.getBranchId(),
									startActivityBean.getSpecializationId(),startActivityBean.getSemesterCode(),
									startActivityBean.getSemesterStartDate(),startActivityBean.getSemesterEndDate(),CRConstant.ACTIVE_STATUS,
									startActivityBean.getUserId(),startActivityBean.getSessionStartDate(),startActivityBean.getSessionEndDate(),
									processCounter);

							countList = new StudentMasterImpl(sqlMapClient,transactionTemplate).generateRollNumbers(activityMasterBean);

							logger.info("Activity : "+startActivityBean.getActivityId()+"for "+startActivityBean.getProgramCourseKey()+" executed successfully");

						}

						//PR7 = pre check validation for new & switch students
						if(activityCode.equalsIgnoreCase("PR7")){

							ActivityMasterBean activityMasterBean=new ActivityMasterBean(startActivityBean.getUniversityId(),
									startActivityBean.getProcessId(),startActivityBean.getActivityId(),
									startActivityBean.getEntityId(),startActivityBean.getProgramId(),startActivityBean.getBranchId(),
									startActivityBean.getSpecializationId(),startActivityBean.getSemesterCode(),
									startActivityBean.getSemesterStartDate(),startActivityBean.getSemesterEndDate(),CRConstant.ACTIVE_STATUS,
									startActivityBean.getUserId(),startActivityBean.getSessionStartDate(),startActivityBean.getSessionEndDate(),
									processCounter);

							countList = new preProcessImpl(sqlMapClient,transactionTemplate).preProcessCheck(activityMasterBean);

						}

						//P7N = pre check validation for normal mode students
						if(activityCode.equalsIgnoreCase("P7N")){

							ActivityMasterBean activityMasterBean=new ActivityMasterBean(startActivityBean.getUniversityId(),
									startActivityBean.getProcessId(),startActivityBean.getActivityId(),
									startActivityBean.getEntityId(),startActivityBean.getProgramId(),startActivityBean.getBranchId(),
									startActivityBean.getSpecializationId(),startActivityBean.getSemesterCode(),
									startActivityBean.getSemesterStartDate(),startActivityBean.getSemesterEndDate(),CRConstant.ACTIVE_STATUS,
									startActivityBean.getUserId(),startActivityBean.getSessionStartDate(),startActivityBean.getSessionEndDate(),
									processCounter);

							countList = new preProcessImpl(sqlMapClient,transactionTemplate).preCheckforMaster(activityMasterBean);

			}

			//MST=Master Transfer will be called
			if(activityCode.equalsIgnoreCase("MST")){
				System.out.println("User Id inside MST"+startActivityBean.getUserId());
				MasterTransferBean masterTransferBean=new MasterTransferBean(startActivityBean.getUniversityId(),
						startActivityBean.getProcessId(),startActivityBean.getActivityId(),
						startActivityBean.getEntityId(),startActivityBean.getProgramId(),startActivityBean.getBranchId(),
						startActivityBean.getSpecializationId(),startActivityBean.getSemesterCode(),
						startActivityBean.getSemesterStartDate(),startActivityBean.getSemesterEndDate(),startActivityBean.getUserId(),
						startActivityBean.getSessionStartDate(),startActivityBean.getSessionEndDate(),startActivityBean.getProgramCourseKey(),processCounter);
				countList=new TransferTempIntoMaster(sqlMapClient,transactionTemplate).transferTempToMaster(masterTransferBean);
				System.out.println("Master Transfer coding ends"+countList.getTotalRecords());
			}

			}

			//Add if condition for Process: ResultProcessing
			if(processCode.equalsIgnoreCase("RSP")){
				//PRE: Preprocess 1
				if(activityCode.equalsIgnoreCase("PRE")){
					countList=new PreProcessForResult(sqlMapClient,transactionTemplate).startPreProcess(startActivityBean);
				}
				//SMR: Preprocess 1 or remedial process
				if(activityCode.equalsIgnoreCase("SMR")){

				}
			}

			//Add if condition for Process: ResultProcessing
			if(processCode.equalsIgnoreCase("SEP")){
				//PR1= Process1 Method TransferNORInPST method will be called.
				if(activityCode.equalsIgnoreCase("PR1")){

				}
			}

			//countList contains
			//1-totalRecord, 2-correctProcessed, 3-rejectedRecord, 4-inErrorRecord and 5-activityCompletedflag

				//If return flag is false for running activity, it will be considered in ERROR
				//If at least one record is in exception in activity, false will be returned
				if(countList.isActivityCompleted()){
					startActivityBean.setProcessStatus(CRConstant.COMPLETE_STATUS);
					startActivityBean.setActivityStatus(CRConstant.COMPLETE_STATUS);
				}
				else{
					startActivityBean.setProcessStatus(CRConstant.ERROR_STATUS);
					startActivityBean.setActivityStatus(CRConstant.ERROR_STATUS);
				}


			//status of activity and process will be updated
			new UpdateActivityAndProcessMaster(sqlMapClient,transactionTemplate).updateActivityStatus(startActivityBean);
			
		}catch(Exception e){
			logger.info("Exception while starting activity");
				
		}
		finally{
			String processFlag=CRConstant.INACTIVE_STATUS;
			boolean processedFlag=false;

			if(countList.getTotalRecords()==countList.getCorrectProcessed() && countList.getTotalRecords()!=0){
				System.out.println("Coming here inside final ");
				processFlag=CRConstant.COMPLETE_STATUS;
				processedFlag=true;
			}
		
			errorLogs.setActualRecord(countList.getTotalRecords());
			errorLogs.setProcessRecord(countList.getCorrectProcessed());
			errorLogs.setFailrecord(countList.getInError()+countList.getRejectedProcessed());
			errorLogs.setRejectedValue(countList.getRejectedProcessed());
			errorLogs.setProcessFlag(processFlag);
			try{
					
			countListforUI.setTotalRecords(countList.getTotalRecords());
			countListforUI.setInError(countList.getInError());
			countListforUI.setRejectedProcessed(countList.getRejectedProcessed());
			countListforUI.setCorrectProcessed(countList.getCorrectProcessed());
			countListforUI.setActivityCompleted(processedFlag);
			
			}catch(Exception e1){
				System.out.println("Exception is"+e1.getMessage());
				
			}
		}

		//This count list object has total number of records to be processed, records in error.
		//return countList;
		}//inTrasactionMethod ends
		});
			
		}//Main try closed
		catch(Exception e){
		logger.info("Process Can't be started"+e.getMessage());
		//return countList;
		}
		
		finally{
			try{
			sqlMapClient.insert("studentTrackingAndLogs.insertBatchLogs",errorLogs);
			}catch(Exception e1){
				System.out.println("Exception is"+e1.getMessage());
			}
		}

		
				return countListforUI;
}//method ends


	/**
	 * It returns ACTIVE session start date and end date according to university
	 * @param universityId
	 * @return
	 */
	public List<StartActivityBean> getSessionDate(String universityId) {
		// TODO Auto-generated method stub
		List<StartActivityBean> sessionDateList=new ArrayList<StartActivityBean>();
		StartActivityBean startActivityBean=new StartActivityBean();
		startActivityBean.setUniversityId(universityId);

		try{
			sessionDateList=sqlMapClient.queryForList("startActivity.getSessionDate",startActivityBean);
			System.out.println(sessionDateList);
		}catch(Exception e){
			System.out.println("Exception e"+e.getMessage());
		}

		return sessionDateList;
	}

	/**
	 * It retruns semester start and end date according to active session
	 * @param startActivityKey
	 * @return
	 */
	public List<StartActivityBean> getSemesterDate(
			StartActivityBean startActivityKey) {

			// TODO Auto-generated method stub
			List<StartActivityBean> semesterDateList=new ArrayList<StartActivityBean>();

				try{
					semesterDateList=sqlMapClient.queryForList("startActivity.getSemesterDate",startActivityKey);
					System.out.println(semesterDateList);
				}catch(Exception e){
					System.out.println("Exception e"+e.getMessage());
				}

			return semesterDateList;
	}
}
